<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>自定义axios请求函数</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/qs/6.11.0/qs.js"></script>
  </head>
  <body>
    <button>点击发送 GET 请求</button>
    <button>点击发送 POST 请求</button>
    <button>点击发送 PUT 请求</button>
    <button>点击发送 DELETE 请求</button>

    <script>

      /* 
      1. 函数的返回值为promise, 成功的结果为response, 异常的结果为error
      2. 能处理多种类型的请求: GET/POST/PUT/DELETE
      3. 函数的参数为一个配置对象
        {

        ​	url: '',  // 请求地址

        ​	method: '',  // 请求方式GET/POST/PUT/DELETE

        ​	params: {},  // GET/DELETE请求的query参数

        ​	data: {}, // POST或PUT请求的请求体参数 

        }
      4. 响应json数据自动解析为js对象
      */

      function axios({url, method='GET', params={}, data={}}) {

        return new Promise((resolve, reject) => {


          /* 处理query参数 */
          // 根据params对象生成查询参数字符串 : {a: 1, b: 2} => a=1&b=2
          const queryStr = Qs.stringify(params)
          // 如果有值, 拼接到url
          if (queryStr) {
            url += '?' + queryStr
          }

          // 将请求方式统一转换为大写
          method = method.toUpperCase()

          // 创建xhr对象
          const xhr = new XMLHttpRequest()
          // 设置请求信息
          xhr.open(method, url)

          // 绑定监听
          xhr.onreadystatechange = () => {
            // 请求完成
            if (xhr.readyState===4) {
              const status = xhr.status
              // 请求成功
              if (status>=200 && status<=299) {
                // 创建response对象
                const response = {
                  data: JSON.parse(xhr.responseText),
                  status,
                  statusText: xhr.statusText
                }
                // 指定为成功的value
                resolve(response)
              } else { // 请求失败
                // 创建error对象
                const error = new Error('请求出错, status=' + status)
                // 指定为失败的reason
                reject(error)
              }
            }
          }

          /* 处理body参数 */
          // 发请求
          if (method==='GET') {
            xhr.send()
          } else {
            // 指定相应的请求头
            xhr.setRequestHeader('Content-Type', 'application/json')
            xhr.send(JSON.stringify(data)) // 指定json格式的请求体
          }
        })
      }


      /* 封装axios的静态方法 */

      axios.get = function (url, config) {
        return axios({...config, url, method: 'GET'})
      }
      axios.delete = function (url, config) {
        return axios({...config, url, method: 'DELETE'})
      }

      axios.post = function (url, data, config) {
        return axios({...config, url, method: 'post', data})
      }

      axios.put = function (url, data, config) {
        return axios({...config, url, method: 'put', data})
      }
    </script>

    <script>
      const buttons = document.querySelectorAll('button')


      buttons[0].onclick = async () => {
        try {
          // const response = await axios({
          //   method: 'GET',
          //   // url: 'http://localhost:3000/movie/2',
          //   url: 'http://localhost:3000/movie',
          //   params: { // 自动转换为query参数
          //     id: 2,
          //     name: '大话西游'
          //   }
          // })
          const response = await axios.get(
            'http://localhost:3000/movie',
            {
              params: { // 自动转换为query参数
                id: 2,
                name: '大话西游'
              }
            }
          )
          console.log(response)
        } catch (error) {
          console.log(error)
          alert(error.message)
        }
      }

      // 添加
      buttons[1].onclick = async () => {
        // const response = await axios({
        //   method: 'post',
        //   url: 'http://localhost:3000/movie',
        //   data: {
        //     name: 'AA',
        //     director: 'BB'
        //   }
        // })

        const response = await axios.post(
          'http://localhost:3000/movie',
          {
            name: 'AA2',
            director: 'BB2'
          }
        )
        console.log(response.data)
      }

      // 更新 
      buttons[2].onclick = async () => {
        // const response = await axios({
        //   method: 'put',
        //   url: 'http://localhost:3000/movie/14',
        //   data: { // 内部会自动转换为Json, 并指定相应Content-Type请求头
        //     name: '野外生存记13',
        //     director: '贝爷13'
        //   }
        // })
        const response = await axios.put(
          'http://localhost:3000/movie/15',
          { 
            name: '野外生存记13',
            director: '贝爷13'
          }
        )
        console.log(response.data)
      }

      // 删除
      buttons[3].onclick = async () => {
        // const response = await axios({
        //   method: 'delete',
        //   url: 'http://localhost:3000/movie/14',
        // })

        const response = await axios.delete('http://localhost:3000/movie/15')
        console.log(response.data)
      }

    </script>


  </body>
</html>
